<?php

/**
 * Created at 2010-5-27 10:00:25
 * @author Jack
 * @code

  //使用示例
  include_once "dataview.class.php";

  //定义回调函数，用来处理特殊列
  function callback_b($col,$row){
  return '<input type="button" value="view_'.$col.'" onclick="alert(0);">';
  }
  function callback_c($col,$row){
  //数组的$col 列值  $row行值
  return date('Y-m-d');
  }

  //主要类
  $view = new dataview();
  echo $view
  ->set_data($data)//二维数组
  //	 ->set_bg('title','red')
  //	 ->set_bg('data',array('blue','yellow'))
  //	 ->set_bg('footer',array('orange','green'))
  ->add_colume('a','标题',300)
  ->add_colume('b','按钮',120,callback_b,'center')
  ->add_colume('c','测试')
  ->add_colume('c','时间',120,callback_c,'center')
  ->set_table('border','1')
  //	 ->add_footer('page control')
  ->add_footer('页面控制','right');

 * @endcode
 */
class dataview {

    private $data;
    private $titles = array();
    private $columes = array();
    private $footers = array();
    //背景颜色
    private $bg_set = array(
        'title_bg' => '', //'#eeeeee',
        'data_bg' => '', //array('#ffffff','#f5f5f5'),
        'footer_bg' => ''//array('#eeeeee')
    );
    //属性设置
    private $property_set = array(
        'table' => array(
            'cellpadding' => 0,
            'cellspacing' => 0,
            'width' => '100%',
        ),
        'tr' => array(
            'height' => '30',
        ),
        'header' => array(
            'height' => '30',
        ),
        'footer' => array(
            'height' => '30',
        ),
        'td' => array(),
        'data' => array()
    );
    //非居中对齐时，表格边空白
    private $black_fill = '&nbsp;';
    //数据空时，提示信息
    private $none_msg = '没有数据';

    public function __construct($data = null) {
        $this->set_data($data);
    }

    /**
     * 获取属性设置
     * */
    private function get_property_set($tag) {
        if (!empty($this->property_set[$tag])) {
            $rt = array();
            foreach ($this->property_set[$tag] as $key => $value) {
                $rt[] = "{$key}=\"{$value}\"";
            }
            return join(' ', $rt);
        } else {
            return '';
        }
    }

    /**
     * 设置属性
     * */
    private function setProperty($tag, $key, $value) {
        $this->property_set[$tag][$key] = $value;
    }

    /**
     * 设置数据源
     * */
    public function set_data($data) {
        $this->data = $data;
        return $this;
    }

    /**
     * 设置背景
     * */
    public function set_bg($tag, $value) {
        $full_key = "{$tag}_bg";
        if (isset($this->bg_set[$full_key])) {
            $this->bg_set[$full_key] = $value;
        }
        return $this;
    }

    /**
     * 增加列
     * */
    public function add_colume($colume_index, $title = null, $width = null, $call_func = null, $align = null, $valign = null) {
        $align = strtolower($align);
        $valign = strtolower($valign);
        $this->columes[] = compact('colume_index', 'title', 'width', 'call_func', 'align', 'valign');
        return $this;
    }

    /**
     * 增加页脚
     * */
    public function add_footer($footer, $align = null, $valign = null) {
        $align = strtolower($align);
        $valign = strtolower($valign);
        $this->footers[] = compact('footer', 'align', 'valign');
        return $this;
    }

    /**
     * 显示表格
     * */
    public function show() {
        if (empty($this->columes)) {
            $this->dbug("columes is empty", __LINE__);
        }
        $rowCount = count($this->data);
        $colCount = count($this->columes);
        $tb_property = $this->get_property_set('table');
        $tr_property = $this->get_property_set('tr');
        $td_property = $this->get_property_set('td');
        $header_property = $this->get_property_set('header');
        $footer_property = $this->get_property_set('footer');

        //表头
        $outHtml = "<table {$tb_property}>";
        $outHtml .= "<tr {$header_property} bgcolor='{$this->bg_set['title_bg']}'>";
        $col = 0;
        foreach ($this->columes as $col_data) {
            extract($col_data);
            $_title = empty($title) ? $colume_index : $title;
            $_width = empty($width) ? "" : "width='{$width}'";
            $outHtml .= "<th {$td_property} {$_width} align='center'>{$_title}</th>";
            $col++;
        }
        $outHtml .= "</tr>";

        //数据
        if (!empty($this->data)) {
            $bg_nums = count($this->bg_set['data_bg']);
            $row = 0;
            foreach ($this->data as $row_data) {
                $bg_row_color = $this->bg_set['data_bg'][$row % $bg_nums];
                $outHtml .= "<tr {$tr_property} bgcolor='{$bg_row_color}'>";
                $col = 0;
                foreach ($this->columes as $col_data) {
                    extract($col_data);
                    $col_value = $row_data[$colume_index];
                    if (!is_null($call_func)) {
                        $col_value = $call_func($col_value, $row_data);
                    }

                    $cur_align = $cur_valign = '';
                    if (in_array($align, array('left', 'center', 'right'))) {
                        $cur_align = "align='{$align}'";
                    }
                    $col_value = empty($align) || $align == 'left' ? ($this->black_fill . $col_value) : $col_value;
                    $col_value .= $align == 'right' ? $this->black_fill : '';
                    if (in_array($valign, array('top', 'center', 'bottom'))) {
                        $cur_valign = "valign='{$valign}'";
                    }
                    $col_values = $col_value != '' ? $col_value : '&nbsp;';
                    $outHtml .= "<td {$td_property} {$cur_align} {$cur_valign}>{$col_values}</td>";
                    $col++;
                }
                $outHtml .= "</tr>";
                $row++;
            }

            //表尾
            if (!empty($this->footers)) {
                $footerCount = count($this->footers);
                $footerBgCount = count($this->bg_set['footer_bg']);
                $row = 0;
                foreach ($this->footers as $cur_footer) {
                    $bg_row_color = $this->bg_set['footer_bg'][$row % $footerBgCount];
                    extract($cur_footer);

                    $cur_align = $cur_valign = '';
                    if (in_array($align, array('left', 'center', 'right'))) {
                        $cur_align = "align='{$align}'";
                    }
                    $footer = empty($align) || $align == 'left' ? ($this->black_fill . $footer) : $footer;
                    $footer .= $align == 'right' ? $this->black_fill : '';
                    if (in_array($valign, array('top', 'center', 'bottom'))) {
                        $cur_valign = "valign='{$valign}'";
                    }

                    $outHtml .= "<tr {$footer_property} bgcolor='{$bg_row_color}'>";
                    $outHtml .= "<td {$td_property} colspan='{$colCount}' {$cur_align} {$cur_valign}>{$footer}</td>";
                    $outHtml .= "</tr>";
                    $row++;
                }
            }
        } else {
            $bg_row_color = $this->bg_set['footer_bg'][0];
            $outHtml .= "<tr {$tr_property} bgcolor='{$bg_row_color}'>";
            $outHtml .= "<td {$td_property} colspan='{$colCount}' align='center'>{$this->none_msg}</td>";
            $outHtml .= "</tr>";
        }
        $outHtml .= "</table>";
        return $outHtml;
    }

    /**
     * 调式信息
     * */
    private function dbug($msg, $line) {
        $self = basename(__FILE__);
        exit("<p>file:[{$self}],line:[{$line}],msg:[{$msg}]</p>");
    }

    public function __toString() {
        return $this->show();
    }

    /**
     * 属性和参数设置
     * */
    public function __call($func, $params) {
        if (preg_match('/^set_([\w]+)/', $func, $match) && !empty($match[1]) && count($params) >= 2) {
            switch ($match[1]) {
                case 'table': {
                        $this->setProperty('table', $params[0], $params[1]);
                        break;
                    }
                case 'tr': {
                        $this->setProperty('tr', $params[0], $params[1]);
                        break;
                    }
                case 'td': {
                        $this->setProperty('td', $params[0], $params[1]);
                        break;
                    }
                case 'header': {
                        $this->setProperty('header', $params[0], $params[1]);
                        break;
                    }
                case 'footer': {
                        $this->setProperty('footer', $params[0], $params[1]);
                        break;
                    }
                case 'black_fill': {
                        $this->black_fill = $params[0];
                        break;
                    }
                case 'none_msg': {
                        $this->none_msg = $params[0];
                        break;
                    }
                default: {
                        break;
                    }
            }
        }
        return $this;
    }

}

?>
